home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / aijournl / 1986_11 / expert.nov < prev    next >
Text File  |  1986-09-25  |  6KB  |  145 lines

  1.  
  2.  
  3.                         Expert's Toolbox
  4.                       by Jonathan Amsterdam
  5.                 November 1986 AI EXPERT magazine
  6.  
  7.  
  8. ;;; SFRL-A Simple Frame Representation Language.
  9. ;; Copyright 1986 by Jonathan Amsterdam.
  10. (DEFVAR *FRAMES* NIL) ; A list of all the frames ever created (with 
  11.                      ; FPUT or DEFFRAME). 
  12. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  13. ;; Interface to SFRL.
  14. ;;; DEFFRAME macro lets you peform several FPUTs at once.  Example:
  15. ;(DEFFRAME MARY-CHUNGS
  16.          CLASSIFICATION INDIVIDUAL
  17.          AKO            CHINESE-RESTAURANT
  18.          CITY           CAMBRIDGE
  19.          LOCATION       CENTRAL-SQUARE
  20.          PRICE          MODERATE
  21.          SERVICE        POOR
  22.          BEST-ITEMS     (SUAN-LA-CHOW-SHOW DUN-DUN-NOODLE))
  23. (DEFMACRO DEFFRAME (NAME &REST SLOTS-AND-VALUES)
  24.  `(PROGN
  25.     (PUSHNEW ',NAME *FRAMES*)    ; PUSHNEW adds an item to a list
  26.                                  ; if it isn't already there.
  27.     ,@(LET ((RESULT NIL))
  28.         (DO ((S-AND-V SLOTS-AND-VALUES (CDDR S-AND-V)))
  29.             ((NULL S-AND-V) (REVERSE RESULT))
  30.           (PUSH `(FPUT ',NAME ',(CAR S-AND-V) ',(CADR S-AND-V))
  31.                 RESULT)))))
  32.  
  33. DEFUN FGET (FRAME SLOT)
  34.  (LET ((VALUE (GET-FACET-WITH-INHERITANCE FRAME SLOT 'VALUE)))
  35.    (OR VALUE
  36.        (RUN-DEMONS-FOR-VALUE 
  37.          (COLLECT-FACET-WITH-INHERITANCE FRAME SLOT 'IF-NEEDED)
  38.          FRAME SLOT))))
  39.  
  40.  ; Only runs demons if something new added.
  41.  (DOLIST (VALUE (IF (LISTP VALUES) VALUES (LIST VALUES)))
  42.    (IF (ADD-TO-FACET FRAME SLOT 'VALUE VALUE)
  43.        (RUN-DEMONS (COLLECT-FACET-WITH-INHERITANCE FRAME SLOT 
  44.                                                    'IF-ADDED)
  45.                    FRAME SLOT 'IF-ADDED VALUE))))
  46. (DEFUN FREMOVE (FRAME SLOT VALUE)
  47.  ; Only runs demons if something actually removed.
  48.  (IF (REMOVE-FROM-FACET FRAME SLOT 'VALUE VALUE)
  49.      (RUN-DEMONS (COLLECT-FACET-WITH-INHERITANCE FRAME SLOT
  50.                                                  'IF-REMOVED)
  51.                  FRAME SLOT 'IF-REMOVED VALUE)))
  52. (DEFUN ADD-DEMON (FRAME SLOT FACET DEMON)
  53.  (IF (NOT (MEMBER FACET '(IF-NEEDED IF-ADDED IF-REMOVED)))
  54.      (ERROR "ADD-DEMON: Bad facet name: ~a" FACET)
  55.      (ADD-TO-FACET FRAME SLOT FACET DEMON)))
  56. (DEFUN REMOVE-DEMON (FRAME SLOT FACET DEMON)
  57.  (IF (NOT (MEMBER FACET '(IF-NEEDED IF-ADDED IF-REMOVED)))
  58.      (ERROR "REMOVE-DEMON: Bad facet name: ~a" FACET)
  59.      (REMOVE-FROM-FACET FRAME SLOT FACET DEMON)))
  60. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  61. ;; Functions for performing inheritance.
  62. (DEFUN GET-FACET-WITH-INHERITANCE (FRAME SLOT FACET)
  63.  (IF (NULL FRAME)
  64.      NIL
  65.      (OR (GET-FACET FRAME SLOT FACET)
  66.          (MAPCAN #'(LAMBDA (F) 
  67.                      (COPY-LIST 
  68.                       (GET-FACET-WITH-INHERITANCE F SLOT FACET)))
  69.                  (GET-FACET FRAME 'AKO 'VALUE)))))
  70. (DEFUN COLLECT-FACET-WITH-INHERITANCE (FRAME SLOT FACET)
  71.  (IF (NULL FRAME)
  72.      NIL
  73.      (APPEND (GET-FACET FRAME SLOT FACET)
  74.              (MAPCAN #'(LAMBDA (F) 
  75.                          (COLLECT-FACET-WITH-INHERITANCE F SLOT 
  76.                                                          FACET))
  77.                      (GET-FACET FRAME 'AKO 'VALUE)))))
  78. ;;; Demons.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  79. (DEFUN ASK-DEMON (FRAME SLOT)
  80.  ; This is a typical IF-NEEDED demon.
  81.  (FORMAT T "~&What is the value of ~a for ~a? " SLOT FRAME)
  82.  (LET ((ANSWER (READ)))
  83.    (FPUT FRAME SLOT ANSWER)
  84.    ANSWER))
  85. (DEFUN INFORM-DEMON (FRAME SLOT VALUE FACET)
  86.  ; This is a typical IF-ADDED/IF-REMOVED demon.
  87.  (IF (EQL FACET 'IF-ADDED)
  88.      (FORMAT T "~&Adding ~a to " VALUE)
  89.      (FORMAT T "~&Removing ~a from " VALUE))
  90.  (FORMAT T "the ~a slot of ~a~%" SLOT FRAME))
  91.              
  92. (DEFUN RUN-DEMONS-FOR-VALUE (DEMON-LIST FRAME SLOT)
  93.  ; Used for IF-NEEDED demons.
  94.  ; Note: this could be implemented as
  95.  ; (SOME #'(LAMBDA (DEMON) (FUNCALL DEMON FRAME SLOT)) DEMON-LIST)
  96.  ; in Common Lisp.
  97.    (LET ((VAL (FUNCALL DEMON FRAME SLOT)))
  98.      (IF VAL
  99.          (RETURN VAL)))))
  100. (DEFUN RUN-DEMONS (DEMON-LIST FRAME SLOT FACET VALUE)
  101.  ; Used for IF-ADDED and IF-REMOVED demons.
  102.  (DOLIST (DEMON DEMON-LIST)
  103.    (FUNCALL DEMON FRAME SLOT VALUE FACET)))
  104. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  105. ;; Low-level functions.
  106. ;;; Facets
  107. ;; A facet is a list (<facet-name> . <values>) where values
  108. ;; must be a list.
  109. (DEFUN GET-FACET (FRAME SLOT FACET)
  110.  (CDR (ASSOC FACET (GET-SLOT FRAME SLOT))))
  111. (DEFUN GET-FACET-FROM-SLOT (SLOT-LIST FACET)
  112.  (CDR (ASSOC FACET SLOT-LIST)))
  113.   ; Returns NIL if VAL is already there.L)
  114.  (LET* ((OLD-SLOT (GET-SLOT FRAME SLOT))
  115.         (OLD-FACET (ASSOC FACET OLD-SLOT))
  116.         (ADDED? T))
  117.    (IF OLD-FACET
  118.        (IF (MEMBER VAL (CDR OLD-FACET))
  119.            (SETQ ADDED? NIL)
  120.            (RPLACD OLD-FACET (CONS VAL (CDR OLD-FACET))))
  121.        (SET-SLOT FRAME SLOT (CONS (LIST FACET VAL) OLD-SLOT)))
  122.    ADDED?))
  123. (DEFUN REMOVE-FROM-FACET (FRAME SLOT FACET VAL)
  124.  ;; Returns T if something actually removed.
  125.  (LET ((OLD-FACET (ASSOC FACET (GET-SLOT FRAME SLOT))))
  126.    (WHEN (AND OLD-FACET (MEMBER VAL (CDR OLD-FACET)))
  127.      (RPLACD OLD-FACET (DELETE VAL (CDR OLD-FACET)))
  128.      T)))
  129.        
  130. ;; Slots
  131. ;; A slot is a list (<slot-name> . <contents> where contents 
  132. ;; is a list of facets. 
  133.   (CDR (ASSOC SLOT (GET FRAME 'FRAME))))
  134. (DEFUN SET-SLOT (FRAME SLOT VAL)
  135.  (LET ((FRAME-LIST (GET FRAME 'FRAME)))
  136.    (LET ((OLD-SLOT (ASSOC SLOT FRAME-LIST)))
  137.      (IF OLD-SLOT
  138.          (RPLACD OLD-SLOT VAL)
  139.          (PUSHNEW FRAME *FRAMES*)
  140.          (SETF (GET FRAME 'FRAME) (CONS (CONS SLOT VAL) 
  141.                                         FRAME-LIST))))))
  142. ;;; End of SFRL code.
  143. TF (GET FRAME 'FRAME) (CONS (CONS SLOT VAL) 
  144.                                         FRAME-LIST))))))
  145. ;;; E